package com.nhim.cms.admin.client.template.ui;

import java.util.ArrayList;
import java.util.List;

import gwtupload.client.IFileInput.FileInputType;
import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.IUploader;
import gwtupload.client.SingleUploader;

import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.nhim.cms.admin.client.rpc.TemplateRPCService;
import com.nhim.cms.admin.client.rpc.TemplateRPCServiceAsync;
import com.nhim.cms.admin.shared.Separator;
import com.nhim.cms.admin.shared.TemplateResourceProxy;

public class TemplateResources extends Composite {

	private static TemplateResourcesUiBinder uiBinder = GWT
			.create(TemplateResourcesUiBinder.class);

	interface TemplateResourcesUiBinder extends
			UiBinder<Widget, TemplateResources> {
	}

	@UiField
	FlowPanel uploadPanel;
	@UiField(provided = true)
	CellTable<TemplateResourceProxy> cellTable;
	private List<AbstractEditableCell<?, ?>> editableCells;
	Integer templateId;

	public TemplateResources() {
		createTable();
		initWidget(uiBinder.createAndBindUi(this));

	}

	// Load the image in the document and in the case of success attach it to
	// the viewer
	private IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
		public void onFinish(IUploader uploader) {
			if (uploader.getStatus() == Status.SUCCESS) {
				bindResources();
			}
		}
	};

	public void Display(Integer templateId) {
		this.templateId = templateId;
		SingleUploader uploader = new SingleUploader(
				FileInputType.BROWSER_INPUT);
		uploader.setFileInputPrefix("1" + Separator.SYSTEM_FILE_UPLOAD_SEPARATOR+ templateId.toString()+ Separator.SYSTEM_FILE_UPLOAD_SEPARATOR);
		uploader.setStyleName("nhim-fileUpload");
		uploadPanel.add(uploader);
		uploader.addOnFinishUploadHandler(onFinishUploaderHandler);
		bindResources();
		
	}
	private final TemplateRPCServiceAsync service = GWT.create(TemplateRPCService.class);
	private void bindResources()
	{
		final List<TemplateResourceProxy> data = dataProvider.getList();
		data.clear();
		service.findAllResources(templateId, new AsyncCallback<List<TemplateResourceProxy>>(){

			@Override
			public void onFailure(Throwable error) {
			
				Window.alert(error.getMessage());
			}

			@Override
			public void onSuccess(List<TemplateResourceProxy> result) {
				for(TemplateResourceProxy proxy : result)
				{
					data.add(proxy);
				}
				if(listener!= null)
					listener.onResourceChange();
				cellTable.redraw();
				
			}});
	}

	/**
	 * Get a cell value from a record.
	 * 
	 * @param <C>
	 *            the cell type
	 */
	private static interface GetValue<C> {
		C getValue(TemplateResourceProxy tempate);
	}

	/**
	 * Add a column with a header.
	 * 
	 * @param <C>
	 *            the cell type
	 * @param cell
	 *            the cell used to render the column
	 * @param headerText
	 *            the header string
	 * @param getter
	 *            the value getter for the cell
	 */
	private <C> Column<TemplateResourceProxy, C> addColumn(Cell<C> cell,
			String headerText, final GetValue<C> getter,
			FieldUpdater<TemplateResourceProxy, C> fieldUpdater) {
		Column<TemplateResourceProxy, C> column = new Column<TemplateResourceProxy, C>(
				cell) {
			@Override
			public C getValue(TemplateResourceProxy object) {
				return getter.getValue(object);
			}
		};
		column.setFieldUpdater(fieldUpdater);
		if (cell instanceof AbstractEditableCell<?, ?>) {
			editableCells.add((AbstractEditableCell<?, ?>) cell);
		}
		cellTable.addColumn(column, headerText);
		return column;
	}

	public static final ProvidesKey<TemplateResourceProxy> KEY_PROVIDER = new ProvidesKey<TemplateResourceProxy>() {
		public Object getKey(TemplateResourceProxy item) {
			return item == null ? null : item.getFileName();
		}
	};
	private ListDataProvider<TemplateResourceProxy> dataProvider = new ListDataProvider<TemplateResourceProxy>();

	private void createTable() {
		// Create the table.
		editableCells = new ArrayList<AbstractEditableCell<?, ?>>();
		cellTable = new CellTable<TemplateResourceProxy>(100, KEY_PROVIDER);
		dataProvider.addDataDisplay(cellTable);
		// TextCell.
		Column<TemplateResourceProxy, String> column = addColumn(new TextCell(), "Name", new GetValue<String>() {
			public String getValue(TemplateResourceProxy ctype) {
				return ctype.getFileName();
			}
		}, null);
		cellTable.setColumnWidth(column, "70%");
		
		Column<TemplateResourceProxy, String> sizeColumn = addColumn(new TextCell(), "Size", new GetValue<String>() {
			public String getValue(TemplateResourceProxy ctype) {
				return ctype.getSize();
			}
		}, null);
		cellTable.setColumnWidth(sizeColumn, "15%");
		
		addColumn(new ButtonCell(), "Action", new GetValue<String>() {
			public String getValue(TemplateResourceProxy template) {
				return "Delete";
			}
		}, new FieldUpdater<TemplateResourceProxy, String>() {
			public void update(int index, final TemplateResourceProxy object,String value)
			{
				final List<TemplateResourceProxy> data = dataProvider.getList();
				if (Window.confirm("Are you sure you want to delete this file?")) 
				{
					
					service.removeResource(templateId, object.getFileName(), new AsyncCallback<Boolean>(){

						@Override
						public void onFailure(Throwable error) {
							Window.alert(error.getMessage());
							
						}

						@Override
						public void onSuccess(Boolean result) {
							if(!result)
								Window.alert("There was an error while deleting the file. Please try again!");
							else
							{
								if(listener != null)
									listener.onResourceChange();
								data.remove(object);
							}
						}});

				} 
				
				cellTable.redraw();
			}
		});

	}
	private Listener listener;

	/**
	 * Custom listener for this widget.
	 */
	public interface Listener {

		/**
		 * Called when the user save Template
		 * 
		 */
		void onResourceChange();
	}

	public void setListener(Listener listener) {
		this.listener = listener;
	}

}
